﻿using System;
using UnityEngine;
using UnityEngine.Networking;

namespace zframe.loader
{
    public enum LoaderStatus {
        Unknown,
        /// <summary>
        /// 加载器初始化完成
        /// </summary>
        Ready,
        /// <summary>
        /// 加载中
        /// </summary>
        Loading,
        /// <summary>
        /// 加载完成
        /// </summary>
        Loaded,
        /// <summary>
        /// 加载器出现了错误
        /// </summary>
        Error,
    }
    public delegate void OnResLoaded(UnityEngine.Object asset, BaseResLoader loader);
    public delegate void OnResError(string error);  

    public class BaseResLoader:ILoader
    {
        protected UnityWebRequest request;
        
        protected string _url;
        protected int _priority;

        protected LoaderStatus _status = LoaderStatus.Unknown; 

        protected UnityEngine.Object _asset;    

        /// <summary>
        /// 正常加载完成时触发的事件
        /// </summary>
        public event OnResLoaded OnResLoaded;
        /// <summary>
        /// 加载出现错误时触发的事件
        /// </summary>
        public event OnResError OnResError;   

        /// <summary>
        /// 正常加载完成时就是加载的资源 否则是null
        /// </summary>
        public UnityEngine.Object Asset { get { return _asset; } } 
        public UnityWebRequest Request { get { return request; } }
        public string Url { get { return _url; } }   
        /// <summary>
        /// 在队列中的优先级，越小优先级越高
        /// </summary>
        public int Priority { get { return _priority; } }

        public BaseResLoader(string url,int priority=0) {
            _url = url; 
            _priority = priority;
            Init(); 
        } 
        /// <summary>
        /// 初始化函数，子类应该始终调用更新状态
        /// </summary>
        protected virtual void Init()
        {
            _status = LoaderStatus.Ready;
        }

        public void Reset(UnityWebRequest req)
        {
            if (req.isDone)
            {
                throw new Exception("不能用已使用过的UnityWebRequest对象重置loader");
            }
            _status = LoaderStatus.Ready;
            request = req;
        }

        /// <summary>
        /// 开始加载
        /// </summary>
        public void Load() {
            if (_status != LoaderStatus.Ready)
            {
                Debug.LogWarning($"Loader只有在{Enum.GetName(typeof(LoaderStatus), LoaderStatus.Ready)}状态才能调用");
                return;
            }
            //调用 SendWebRequest 方法开始与远程服务器进行通信后，
            //UnityWebRequest 对象的大部分属性将无法更改。就是基本不能复用 需要重新new
            UnityWebRequestAsyncOperation opt = request.SendWebRequest();
            SetStatus(LoaderStatus.Loading);
            opt.completed += LoadComplete;
        }

        protected void LoadComplete(AsyncOperation opt)
        {
            if (request.isHttpError || request.isNetworkError)
            {
                SetStatus(LoaderStatus.Error);
                OnError(request.error);
            }
            else
            {
                SetStatus(LoaderStatus.Loaded);
                
            }
            OnLoaded();
        }

        /// <summary>
        /// 加载完成 子类应该始终调触发事件或自行调用ExecuteLoaded
        /// </summary>
        /// <param name="opt"></param>
        protected virtual void OnLoaded()
        {
            ExecuteLoaded();
        }

        protected void ExecuteLoaded()
        {
            if (_status == LoaderStatus.Loaded && OnResLoaded!=null)
            {
                OnResLoaded.Invoke(_asset,this);
            }
            
        }

        protected virtual void SetStatus(LoaderStatus status)
        {
            _status = status;
        }

        protected virtual void OnError(string error)
        {
            if (OnResError!=null)
            {
                OnResError.Invoke(error);
            }

        }

    }
}
